<!DOCTYPE html>
<html lang="en-us">
  <head>
    
    <script type="application/ld+json">

{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Multimedia",
  
  "datePublished": "2022-03-31T20:38:17+08:00",
  "dateModified": "2022-03-31T20:38:17+08:00",
  "author": {
    "@type": "Person",
    "name": "Zhang Gaojie",
    
    "image": "https://zgjoget.gitee.io/img/avatar.jpg"
    
  },
  "mainEntityOfPage": { 
    "@type": "WebPage",
    "@id": "https:\/\/zgjoget.gitee.io\/2022\/03\/multimedia\/" 
  },
  "publisher": {
    "@type": "Organization",
    "name": "Zhang Gaojie",
    
    "logo": {
      "@type": "ImageObject",
      "url": "https://zgjoget.gitee.io/img/avatar.jpg"
    }
    
  },
  "description": "多媒体技术\n",
  "keywords": []
}

</script>
    <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="generator" content="Hugo 0.92.2 with theme Tranquilpeak 0.5.3-BETA">
<meta name="author" content="Zhang Gaojie">
<meta name="keywords" content="">
<meta name="description" content="多媒体技术">


<meta property="og:description" content="多媒体技术">
<meta property="og:type" content="article">
<meta property="og:title" content="Multimedia">
<meta name="twitter:title" content="Multimedia">
<meta property="og:url" content="https://zgjoget.gitee.io/2022/03/multimedia/">
<meta property="twitter:url" content="https://zgjoget.gitee.io/2022/03/multimedia/">
<meta property="og:site_name" content="Zhang Gaojie">
<meta property="og:description" content="多媒体技术">
<meta name="twitter:description" content="多媒体技术">
<meta property="og:locale" content="en-us">

  
    <meta property="article:published_time" content="2022-03-31T20:38:17">
  
  
    <meta property="article:modified_time" content="2022-03-31T20:38:17">
  
  
  
  


<meta name="twitter:card" content="summary">







  <meta property="og:image" content="https://zgjoget.gitee.io/img/avatar.jpg">
  <meta property="twitter:image" content="https://zgjoget.gitee.io/img/avatar.jpg">






    <title>Multimedia</title>

    <link rel="icon" href="https://zgjoget.gitee.io/favicon.png">
    

    

    <link rel="canonical" href="https://zgjoget.gitee.io/2022/03/multimedia/">

    
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css" integrity="sha512-H9jrZiiopUdsLpg94A333EfumgUBpO9MdbxStdeITo+KEIMaNfHNvwyjjDJb+ERPaRS6DpyRlKbvPUasNItRyw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    
    
    
    <link rel="stylesheet" href="https://zgjoget.gitee.io/css/style-h6ccsoet3mzkbb0wngshlfbaweimexgqcxj0h5hu4h82olsdzz6wmqdkajm.min.css" />
    
    

    
      
    
    
  </head>

  <body>
    <div id="blog">
      <header id="header" data-behavior="4">
  <i id="btn-open-sidebar" class="fa fa-lg fa-bars"></i>
  <div class="header-title">
    <a class="header-title-link" href="https://zgjoget.gitee.io/" aria-label="Go to homepage">Zhang Gaojie</a>
  </div>
  
    
      <a class="header-right-picture "
         href="https://zgjoget.gitee.io/#about" aria-label="Open the link: /#about">
    
    
    
      
        <img class="header-picture" src="https://zgjoget.gitee.io/img/avatar.jpg" alt="Author&#39;s picture" />
      
    
    </a>
  
</header>

      <nav id="sidebar" data-behavior="4">
  <div class="sidebar-container">
    
      <div class="sidebar-profile">
        <a href="https://zgjoget.gitee.io/#about" aria-label="Read more about the author">
          <img class="sidebar-profile-picture" src="https://zgjoget.gitee.io/img/avatar.jpg" alt="Author&#39;s picture" />
        </a>
        <h4 class="sidebar-profile-name">Zhang Gaojie</h4>
        
          <h5 class="sidebar-profile-bio">A Computer-science and Cyber-security novice</h5>
        
      </div>
    
    <ul class="sidebar-buttons">
      
  <li class="sidebar-button">
    
      <a class="sidebar-button-link " href="https://zgjoget.gitee.io/" title="Home">
    
      <i class="sidebar-button-icon fas fa-lg fa-home" aria-hidden="true"></i>
      
      <span class="sidebar-button-desc">Home</span>
    </a>
  </li>

  <li class="sidebar-button">
    
      <a class="sidebar-button-link " href="https://zgjoget.gitee.io/categories" title="Categories">
    
      <i class="sidebar-button-icon fas fa-lg fa-bookmark" aria-hidden="true"></i>
      
      <span class="sidebar-button-desc">Categories</span>
    </a>
  </li>

  <li class="sidebar-button">
    
      <a class="sidebar-button-link " href="https://zgjoget.gitee.io/tags" title="Tags">
    
      <i class="sidebar-button-icon fas fa-lg fa-tags" aria-hidden="true"></i>
      
      <span class="sidebar-button-desc">Tags</span>
    </a>
  </li>

  <li class="sidebar-button">
    
      <a class="sidebar-button-link " href="https://zgjoget.gitee.io/archives" title="Archives">
    
      <i class="sidebar-button-icon fas fa-lg fa-archive" aria-hidden="true"></i>
      
      <span class="sidebar-button-desc">Archives</span>
    </a>
  </li>

  <li class="sidebar-button">
    
      <a class="sidebar-button-link " href="https://zgjoget.gitee.io/#about" title="About">
    
      <i class="sidebar-button-icon fas fa-lg fa-question" aria-hidden="true"></i>
      
      <span class="sidebar-button-desc">About</span>
    </a>
  </li>


    </ul>
    <ul class="sidebar-buttons">
      
  <li class="sidebar-button">
    
      <a class="sidebar-button-link " href="https://github.com/zgjoget9" target="_blank" rel="noopener" title="GitHub">
    
      <i class="sidebar-button-icon fab fa-lg fa-github" aria-hidden="true"></i>
      
      <span class="sidebar-button-desc">GitHub</span>
    </a>
  </li>

  <li class="sidebar-button">
    
      <a class="sidebar-button-link " href="https://stackoverflow.com/users/18013715/jack-zhang" target="_blank" rel="noopener" title="Stack Overflow">
    
      <i class="sidebar-button-icon fab fa-lg fa-stack-overflow" aria-hidden="true"></i>
      
      <span class="sidebar-button-desc">Stack Overflow</span>
    </a>
  </li>


    </ul>
    <ul class="sidebar-buttons">
      

    </ul>
  </div>
</nav>

      

      <div id="main" data-behavior="4"
        class="
               hasCoverMetaIn
               ">
        <article class="post" id="top">
          
          
            <div class="post-header main-content-wrap text-left">
  
    <h1 class="post-title">
      Multimedia
    </h1>
  
  
  <div class="postShorten-meta post-meta">
    
      <time datetime="2022-03-31T20:38:17&#43;08:00">
        
  March 31, 2022

      </time>
    
    
  </div>

</div>
          
          <div class="post-content markdown">
            <div class="main-content-wrap">
              <p>多媒体技术</p>
<h2 id="通知">通知</h2>
<p>通知是Android系统中比较有特色的一个功能，当某个应用程序希望向用户发出一些提示信息，而该应用程序又不在前台运行时，就可以借助通知来实现。发出一条通知后，手机最上方的状态栏中会显示一个通知的图标，下拉状态栏后可以看到通知的详细内容。</p>
<h3 id="通知渠道">通知渠道</h3>
<p>Android 8.0系统引入了通知渠道这个概念。</p>
<p>通知渠道，顾名思义，就是每条通知都要属于一个对应的渠道。每个应用程序都可以自由地创建当前应用拥有哪些通知渠道，但是这些通知渠道的控制权是掌握在用户手上的。用户可以自由地选择这些通知渠道的重要程度，是否响铃、是否振动或者是否要关闭这个渠道的通知。</p>
<p>对于每个应用来说，通知渠道的划分是非常考究的，因为通知渠道一旦创建之后就不能再修改了，因此开发者需要仔细分析自己的应用程序一共有哪些类型的通知，然后再去创建相应的通知渠道。</p>
<p>我们可以参考Twitter的通知渠道划分，如右图所示。</p>
<p><img src="https://zgjoget9.github.io/img/content_provider_1.png" alt="pic1"></p>
<h3 id="创建通知渠道">创建通知渠道</h3>
<p>创建一个通知渠道至少需要渠道ID、渠道名称以及重要等级这3个参数，其中渠道ID可以随便定义，只要保证全局唯一性就可以。</p>
<p>渠道名称是给用户看的，需要可以清楚地表达这个渠道的用途。</p>
<p>通知的重要等级主要有IMPORTANCE_HIGH、IMPORTANCE_DEFAULT、IMPORTANCE_LOW、IMPORTANCE_MIN这几种，对应的重要程度依次从高到低，不同的重要等级会决定通知的不同行为。</p>
<p>示例代码如下所示：</p>
<pre tabindex="0"><code>if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O) {
    val channel = NotificationChannel(channelId, channelName, importance)
    manager.createNotificationChannel(channel)
}

</code></pre><h3 id="通知的基本用法">通知的基本用法</h3>
<p>想要让手机弹出一条通知，只需要使用如下代码：</p>
<pre tabindex="0"><code>val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val notification = NotificationCompat.Builder(context, channelId)
        .setContentTitle(&quot;This is content title&quot;)
        .setContentText(&quot;This is content text&quot;)
        .setSmallIcon(R.drawable.small_icon)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.large_icon))
        .build()
manager.notify(1, notification)
</code></pre><p>想要指定通知的点击事件，只需要使用如下代码：</p>
<pre tabindex="0"><code>val intent = Intent(this, NotificationActivity::class.java)
val pi = PendingIntent.getActivity(this, 0, intent, 0)
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val notification = NotificationCompat.Builder(context, channelId)
        .setContentTitle(&quot;This is content title&quot;)
        .setContentText(&quot;This is content text&quot;)
        .setSmallIcon(R.drawable.small_icon)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.large_icon))
        .setContentIntent(pi)
        .build()
manager.notify(1, notification)
</code></pre><h3 id="显示长文字的通知">显示长文字的通知</h3>
<p>使用setStyle()方法替代setContentText()方法，并在setStyle()方法中创建一个NotificationCompat.BigTextStyle对象，这个对象就是用于封装长文字信息的，
只要调用它的bigText()方法并将文字内容传入就可以了。</p>
<pre tabindex="0"><code>val notification = NotificationCompat.Builder(this, &quot;normal&quot;)
        ...
        .setStyle(NotificationCompat.BigTextStyle().bigText(&quot;Learn how to build notifications, send and sync  data, and use voice actions. Get the official Android IDE and developer tools to build apps for Android.&quot;))
       .build()
</code></pre><h3 id="显示大图片的通知">显示大图片的通知</h3>
<p>仍然调用的setStyle()方法，在参数中创建一个NotificationCompat.BigPictureStyle对象，这个对象就是用于设置大图片的，然后调用它的bigPicture()方法并将图片传入即可。</p>
<pre tabindex="0"><code>val notification = NotificationCompat.Builder(this, &quot;normal&quot;)
        ...
        .setStyle(NotificationCompat.BigPictureStyle().bigPicture(
		BitmapFactory.decodeResource(resources, R.drawable.big_image)))
        .build()
</code></pre><h2 id="调用摄像头和相册">调用摄像头和相册</h2>
<h3 id="调用摄像头拍照">调用摄像头拍照</h3>
<p>虽然Android赋予我们了在应用程序中打开摄像头拍照的能力，但是通常情况下并没有必要这么做，因为我们可以直接打开系统的相机程序进行拍照，然后获取返回的图片即可。示例代码如下：</p>
<pre tabindex="0"><code>class MainActivity : AppCompatActivity() {
    lateinit var imageUri: Uri
    lateinit var outputImage: File
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        outputImage = File(externalCacheDir, &quot;output_image.jpg&quot;)
        if (outputImage.exists()) {
            outputImage.delete()
        }
        outputImage.createNewFile()
        imageUri = if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.N) {
            FileProvider.getUriForFile(this, &quot;com.example.cameraalbumtest.fileprovider&quot;, outputImage)
        } else {
            Uri.fromFile(outputImage)
        }
        val intent = Intent(&quot;android.media.action.IMAGE_CAPTURE&quot;)
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
        startActivityForResult(intent, takePhoto)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            takePhoto -&gt; {
                if (resultCode == Activity.RESULT_OK) {val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))
                    imageView.setImageBitmap( bitmap)
                }
            }
        }
    }
    ...
}
</code></pre><p>从Android 7.0系统开始，直接使用本地真实路径的Uri被认为是不安全的，会抛出一个FileUriExposedException异常。而FileProvider则是一种特殊的ContentProvider，它可以选择性地将封装过的Uri共享给外部，从而提高了应用的安全性。</p>
<p>为此我们需要再额外配置一个Uri的共享路径，右击res目录→New→Directory，创建一个xml目录，接着右击xml目录→New→File，创建一个file_paths.xml文件。然后修改file_paths.xml文件中的内容，如下所示：</p>
<pre tabindex="0"><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;paths xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
    &lt;external-path name=&quot;my_images&quot; path=&quot;/&quot; /&gt;
&lt;/paths&gt;
</code></pre><p>然后在AndroidManifest中对FileProvider进行注册即可：</p>
<pre tabindex="0"><code>&lt;provider
    android:name=&quot;androidx.core.content.FileProvider&quot;
    android:authorities=&quot;com.example.cameraalbumtest.fileprovider&quot;
    android:exported=&quot;false&quot;
    android:grantUriPermissions=&quot;true&quot;&gt;
    &lt;meta-data
        android:name=&quot;android.support.FILE_PROVIDER_PATHS&quot;
        android:resource=&quot;@xml/file_paths&quot; /&gt;
&lt;/provider&gt;
</code></pre><p>现在就可以打开相机进行拍照了，最终的运行结果如下图所示。</p>
<p>！<a href="https://zgjoget9.github.io/img/content_provider_2.png">pic2</a></p>
<h3 id="从相册中选择图片">从相册中选择图片</h3>
<p>虽然调用摄像头拍照既方便又快捷，但我们并不是每次都需要当场拍一张照片的。因为每个人的手机相册里应该都会存有许多张图片，直接从相册里选取一张现有的图片会比打开相机拍一张照片更加常用。示例代码如下：</p>
<pre tabindex="0"><code>class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
        intent.addCategory(Intent.CATEGORY_OPENABLE) 
        intent.type = &quot;image/*&quot;
        startActivityForResult(intent, fromAlbum)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            fromAlbum -&gt; {
                if (resultCode == Activity.RESULT_OK &amp;&amp; data != null) {
                    data.data?.let { uri -&gt;
                        val bitmap = getBitmapFromUri(uri)
                        imageView.setImageBitmap(bitmap)
                    }
                }
            }
        }
    }

    private fun getBitmapFromUri(uri: Uri) = contentResolver.openFileDescriptor(uri, &quot;r&quot;)?.use {
        BitmapFactory.decodeFileDescriptor(it.fileDescriptor)
    }
    …
}
</code></pre><h2 id="播放多媒体文件">播放多媒体文件</h2>
<h3 id="播放音频">播放音频</h3>
<p>手机上最常见的休闲方式毫无疑问就是听音乐和看电影了，随着移动设备的普及，越来越多的人可以随时享受优美的音乐，观看精彩的电影。Android在播放音频和视频方面做了相当不错的支持，它提供了一套较为完整的API，使得开发者可以很轻松地编写出一个简易的音频或视频播放器。</p>
<p>在Android中播放音频文件一般都是使用MediaPlayer类实现的，它对多种格式的音频文件提供了非常全面的控制方法，从而使播放音乐的工作变得十分简单。下表列出了MediaPlayer类中一些较为常用的控制方法。</p>
<p><img src="https://zgjoget9.github.io/img/content_provider_3.png" alt="pic3"></p>
<p>一个简单的音乐播放器示例代码如下：</p>
<pre tabindex="0"><code>class MainActivity : AppCompatActivity() {

    private val mediaPlayer = MediaPlayer()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initMediaPlayer()
        play.setOnClickListener {
            if (!mediaPlayer.isPlaying) {
                mediaPlayer.start() // 开始播放
            }
        }
        pause.setOnClickListener {
            if (mediaPlayer.isPlaying) {
                mediaPlayer.pause() // 暂停播放
            }
        }
        stop.setOnClickListener {
            if (mediaPlayer.isPlaying) {
                mediaPlayer.reset() // 停止播放
                initMediaPlayer()
            }
        }
    }

    private fun initMediaPlayer() {
        val assetManager = assets
        val fd = assetManager.openFd(&quot;music.mp3&quot;)
        mediaPlayer.setDataSource(fd.fileDescriptor, fd.startOffset, fd.length) 
        mediaPlayer.prepare()
    }

    override fun onDestroy() {
        super.onDestroy()
        mediaPlayer.stop()
        mediaPlayer.release()
    }

}
</code></pre><h3 id="播放视频">播放视频</h3>
<p>播放视频文件其实并不比播放音频文件复杂，主要是使用VideoView类来实现的。这个类将视频的显示和控制集于一身，我们仅仅借助它就可以完成一个简易的视频播放器。VideoView的用法和MediaPlayer也比较类似，下表列出了MediaPlayer类中一些较为常用的控制方法。</p>
<p><img src="https://zgjoget9.github.io/img/content_provider_4.png" alt="pic4"></p>
<p>一个简单的视频播放器示例代码如下：</p>
<pre tabindex="0"><code>class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val uri = Uri.parse(&quot;android.resource://$packageName/${R.raw.video}&quot;)
        videoView.setVideoURI(uri)
        play.setOnClickListener {
            if (!videoView.isPlaying) {
                videoView.start() // 开始播放
            }
        }
        pause.setOnClickListener {
            if (videoView.isPlaying) {
                videoView.pause() // 暂停播放
            }
        }
        replay.setOnClickListener {
            if (videoView.isPlaying) {
                videoView.resume() // 重新播放
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        videoView.suspend()
    }

}
</code></pre><h2 id="kotlin使用infix函数构建更可读的语法">kotlin:使用infix函数构建更可读的语法</h2>
<p>借助infix函数，我们可以使用一种更具可读性的语法来表达一段代码。</p>
<pre tabindex="0"><code>infix fun String.beginsWith(prefix: String) = startsWith(prefix)
</code></pre><p>这里给String类添加了一个beginsWith()函数，它用于判断一个字符串是否是以某个指定参数开头。而加上了infix关键字之后，beginsWith()函数就变成了一个infix函数，这样除了传统的函数调用方式之外，我们还可以用一种特殊的语法糖格式调用beginsWith()函数，如下所示：</p>
<pre tabindex="0"><code>if (&quot;Hello Kotlin&quot; beginsWith &quot;Hello&quot;) {
    // 处理具体的逻辑
}
</code></pre><p>我们还可以给Collection接口添加一个扩展函数：</p>
<pre tabindex="0"><code>infix fun &lt;T&gt; Collection&lt;T&gt;.has(element: T) = contains(element)
</code></pre><p>现在我们就可以使用如下的语法来判断集合中是否包括某个指定的元素：</p>
<pre tabindex="0"><code>val list = listOf(&quot;Apple&quot;, &quot;Banana&quot;, &quot;Orange&quot;, &quot;Pear&quot;, &quot;Grape&quot;)
if (list has &quot;Banana&quot;) {
    // 处理具体的逻辑
}
</code></pre>
              


            </div>
          </div>
          <div id="post-footer" class="post-footer main-content-wrap">
            
              
            
            
<div class="post-actions-wrap">
  <nav >
    <ul class="post-actions post-action-nav">
      
        <li class="post-action">
          
            <a class="post-action-btn btn btn--default tooltip--top" href="https://zgjoget.gitee.io/2022/04/service/" data-tooltip="Service" aria-label="NEXT: Service">
          
              <i class="fa fa-angle-left"></i>
              <span class="hide-xs hide-sm text-small icon-ml">NEXT</span>
            </a>
        </li>
        <li class="post-action">
          
            <a class="post-action-btn btn btn--default tooltip--top" href="https://zgjoget.gitee.io/2022/03/contentprovider/" data-tooltip="ContentProvider" aria-label="PREVIOUS: ContentProvider">
          
              <span class="hide-xs hide-sm text-small icon-mr">PREVIOUS</span>
              <i class="fa fa-angle-right"></i>
            </a>
        </li>
      
    </ul>
  </nav>
<ul class="post-actions post-action-share" >
  
    <li class="post-action hide-lg hide-md hide-sm">
      <a class="post-action-btn btn btn--default btn-open-shareoptions" href="#btn-open-shareoptions" aria-label="Share this post">
        <i class="fa fa-share-alt" aria-hidden="true"></i>
      </a>
    </li>
    
      <li class="post-action hide-xs">
        <a class="post-action-btn btn btn--default" target="new" href="https://www.facebook.com/sharer/sharer.php?u=https://zgjoget.gitee.io/2022/03/multimedia/" title="Share on Facebook" aria-label="Share on Facebook">
          <i class="fab fa-facebook-square" aria-hidden="true"></i>
        </a>
      </li>
    
      <li class="post-action hide-xs">
        <a class="post-action-btn btn btn--default" target="new" href="https://twitter.com/intent/tweet?text=https://zgjoget.gitee.io/2022/03/multimedia/" title="Share on Twitter" aria-label="Share on Twitter">
          <i class="fab fa-twitter" aria-hidden="true"></i>
        </a>
      </li>
    
      <li class="post-action hide-xs">
        <a class="post-action-btn btn btn--default" target="new" href="https://www.linkedin.com/sharing/share-offsite/?url=https://zgjoget.gitee.io/2022/03/multimedia/" title="Share on Linkedin" aria-label="Share on Linkedin">
          <i class="fab fa-linkedin" aria-hidden="true"></i>
        </a>
      </li>
    
  
  
    <li class="post-action">
      <a class="post-action-btn btn btn--default" href="#disqus_thread" aria-label="Leave a comment">
        <i class="far fa-comment"></i>
      </a>
    </li>
  
  <li class="post-action">
    
      <a class="post-action-btn btn btn--default" href="#top" aria-label="Back to top">
      <i class="fa fa-arrow-up" aria-hidden="true"></i>
    
    </a>
  </li>
</ul>
</div>


            
  
    <div id="disqus_thread">
      <noscript>Please enable JavaScript to view the comments powered by Disqus.</noscript>
    </div>
    <script type="text/javascript">
      var disqus_config = function() {
        this.page.url = 'https:\/\/zgjoget.gitee.io\/2022\/03\/multimedia\/';
        
          this.page.identifier = '\/2022\/03\/multimedia\/'
        
      };
      (function() {
        
        
        if (["localhost", "127.0.0.1"].indexOf(window.location.hostname) != -1) {
          document.getElementById('disqus_thread').innerHTML = 'Disqus comments not available by default when the website is previewed locally.';
          return;
        }
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        var disqus_shortname = 'zgjoget9-github-io';
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
      })();
    </script>
  


          </div>
        </article>
        <footer id="footer" class="main-content-wrap">
  <span class="copyrights">
    &copy; 2022 Zhang Gaojie. All Rights Reserved
  </span>
</footer>

      </div>
      <div id="bottom-bar" class="post-bottom-bar" data-behavior="4">
        
<div class="post-actions-wrap">
  <nav >
    <ul class="post-actions post-action-nav">
      
        <li class="post-action">
          
            <a class="post-action-btn btn btn--default tooltip--top" href="https://zgjoget.gitee.io/2022/04/service/" data-tooltip="Service" aria-label="NEXT: Service">
          
              <i class="fa fa-angle-left"></i>
              <span class="hide-xs hide-sm text-small icon-ml">NEXT</span>
            </a>
        </li>
        <li class="post-action">
          
            <a class="post-action-btn btn btn--default tooltip--top" href="https://zgjoget.gitee.io/2022/03/contentprovider/" data-tooltip="ContentProvider" aria-label="PREVIOUS: ContentProvider">
          
              <span class="hide-xs hide-sm text-small icon-mr">PREVIOUS</span>
              <i class="fa fa-angle-right"></i>
            </a>
        </li>
      
    </ul>
  </nav>
<ul class="post-actions post-action-share" >
  
    <li class="post-action hide-lg hide-md hide-sm">
      <a class="post-action-btn btn btn--default btn-open-shareoptions" href="#btn-open-shareoptions" aria-label="Share this post">
        <i class="fa fa-share-alt" aria-hidden="true"></i>
      </a>
    </li>
    
      <li class="post-action hide-xs">
        <a class="post-action-btn btn btn--default" target="new" href="https://www.facebook.com/sharer/sharer.php?u=https://zgjoget.gitee.io/2022/03/multimedia/" title="Share on Facebook" aria-label="Share on Facebook">
          <i class="fab fa-facebook-square" aria-hidden="true"></i>
        </a>
      </li>
    
      <li class="post-action hide-xs">
        <a class="post-action-btn btn btn--default" target="new" href="https://twitter.com/intent/tweet?text=https://zgjoget.gitee.io/2022/03/multimedia/" title="Share on Twitter" aria-label="Share on Twitter">
          <i class="fab fa-twitter" aria-hidden="true"></i>
        </a>
      </li>
    
      <li class="post-action hide-xs">
        <a class="post-action-btn btn btn--default" target="new" href="https://www.linkedin.com/sharing/share-offsite/?url=https://zgjoget.gitee.io/2022/03/multimedia/" title="Share on Linkedin" aria-label="Share on Linkedin">
          <i class="fab fa-linkedin" aria-hidden="true"></i>
        </a>
      </li>
    
  
  
    <li class="post-action">
      <a class="post-action-btn btn btn--default" href="#disqus_thread" aria-label="Leave a comment">
        <i class="far fa-comment"></i>
      </a>
    </li>
  
  <li class="post-action">
    
      <a class="post-action-btn btn btn--default" href="#top" aria-label="Back to top">
      <i class="fa fa-arrow-up" aria-hidden="true"></i>
    
    </a>
  </li>
</ul>
</div>


      </div>
      
<div id="share-options-bar" class="share-options-bar" data-behavior="4">
  <i id="btn-close-shareoptions" class="fa fa-times"></i>
  <ul class="share-options">
    
      <li class="share-option">
        <a class="share-option-btn" target="new" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fzgjoget.gitee.io%2F2022%2F03%2Fmultimedia%2F" aria-label="Share on Facebook">
          <i class="fab fa-facebook-square" aria-hidden="true"></i><span>Share on Facebook</span>
        </a>
      </li>
    
      <li class="share-option">
        <a class="share-option-btn" target="new" href="https://twitter.com/intent/tweet?text=https%3A%2F%2Fzgjoget.gitee.io%2F2022%2F03%2Fmultimedia%2F" aria-label="Share on Twitter">
          <i class="fab fa-twitter" aria-hidden="true"></i><span>Share on Twitter</span>
        </a>
      </li>
    
      <li class="share-option">
        <a class="share-option-btn" target="new" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fzgjoget.gitee.io%2F2022%2F03%2Fmultimedia%2F" aria-label="Share on Linkedin">
          <i class="fab fa-linkedin" aria-hidden="true"></i><span>Share on Linkedin</span>
        </a>
      </li>
    
  </ul>
</div>
<div id="share-options-mask" class="share-options-mask"></div>


    </div>
    
    <div id="about">
  <div id="about-card">
    <div id="about-btn-close">
      <i class="fa fa-times"></i>
    </div>
    
      <img id="about-card-picture" src="https://zgjoget.gitee.io/img/avatar.jpg" alt="Author&#39;s picture" />
    
    <h4 id="about-card-name">Zhang Gaojie</h4>
    
      <div id="about-card-bio">A Computer-science and Cyber-security novice</div>
    
    
      <div id="about-card-job">
        <i class="fa fa-briefcase"></i>
        <br/>
        Huazhong University of Science and Technology
      </div>
    
    
      <div id="about-card-location">
        <i class="fa fa-map-marker-alt"></i>
        <br/>
        Wuhan, China
      </div>
    
  </div>
</div>

    

    
  
    
      <div id="cover" style="background-image:url('https://zgjoget.gitee.io/images/cover.jpg');"></div>
    
  


    
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/highlight.min.js" integrity="sha512-z+/WWfyD5tccCukM4VvONpEtLmbAm5LDu7eKiyMQJ9m7OfPEDL7gENyDRL3Yfe8XAuGsS2fS4xSMnl6d30kqGQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js" integrity="sha512-uURl+ZXMBrF4AwGaWmEetzrd+J5/8NRkWAvJx5sbPSSuOb0bZLqf+tOzniObO00BjHa/dD7gub9oCGMLPQHtQA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>


<script src="https://zgjoget.gitee.io/js/script-yqzy9wdlzix4lbbwdnzvwx3egsne77earqmn73v9uno8aupuph8wfguccut.min.js"></script>


  
    <script async crossorigin="anonymous" defer integrity="sha512-gE8KAQyFIzV1C9+GZ8TKJHZS2s+n7EjNtC+IMRn1l5+WYJTHOODUM6JSjZhFhqXmc7bG8Av6XXpckA4tYhflnw==" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/languages/apache.min.js"></script>
  

  
    <script async crossorigin="anonymous" defer integrity="sha512-EWROca+bote+7Oaaar1F6y74iZj1r1F9rm/ly7o+/FwJopbBaWtsFDmaKoZDd3QiGU2pGacBirHJNivmGLYrow==" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/languages/go.min.js"></script>
  

  
    <script async crossorigin="anonymous" defer integrity="sha512-GDVzAn0wpx1yVtQsRWmFc6PhJiLBPdUic+h4GWgljBh904O3JU10fk9EKNpVyIoPqkFn54rgL2QBG4BmUTMpiQ==" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/languages/http.min.js"></script>
  

  
    <script async crossorigin="anonymous" defer integrity="sha512-UgZlma8NzkrDb/NWgmLIcTrH7i/CSnLLDRFqCSNF5NGPpjKmzyM25qcoXGOup8+cDakKyaiTDd7N4dyH4YT+IA==" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/languages/less.min.js"></script>
  

  
    <script async crossorigin="anonymous" defer integrity="sha512-lot9koe73sfXIrUvIPM/UEhuMciN56RPyBdOyZgfO53P2lkWyyXN7J+njcxIIBRV+nVDQeiWtiXg+bLAJZDTfg==" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/languages/nginx.min.js"></script>
  

  
    <script async crossorigin="anonymous" defer integrity="sha512-Zd3e7XxHP00TD0Imr0PIfeM0fl0v95kMWuhyAS3Wn1UTSXTkz0OhtRgBAr4JlmADRgiXr4x7lpeUdqaGN8xIog==" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/languages/puppet.min.js"></script>
  

  
    <script async crossorigin="anonymous" defer integrity="sha512-qtqDO052iXMSP+5d/aE/jMtL9vIIGvONgTJziC2K/ZIB1yEGa55WVxGE9/08rSQ62EoDifS9SWVGZ7ihSLhzMA==" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/languages/scss.min.js"></script>
  

  
    <script async crossorigin="anonymous" defer integrity="sha512-1NmkjnEDnwwwcu28KoQF8vs3oaPFokQHbmbtwGhFfeDsQZtVFI8zW2aE9O8yMYdpdyKV/5blE4pSWw4Z/Sv97w==" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/languages/stylus.min.js"></script>
  

  
    <script async crossorigin="anonymous" defer integrity="sha512-B2wSfruPjr8EJL6IIzQr1eAuDwrsfIfccNf/LCEdxELCgC/S/ZMt/Uvk80aD79m7IqOqW+Sw8nbkvha20yZpzg==" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/languages/swift.min.js"></script>
  

  
    <script async crossorigin="anonymous" defer integrity="sha512-28oDiQZGKUVN6wQ7PSLPNipOcmkCALXKwOi7bnkyFf8QiMZQxG9EQoy/iiNx6Zxj2cG2SbVa4dXKigQhu7GiFw==" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/languages/yaml.min.js"></script>
  


<script>
$(document).ready(function() {
  hljs.configure({ classPrefix: '', useBR: false });
  $('pre.code-highlight > code, pre > code').each(function(i, block) {
    if (!$(this).hasClass('codeblock')) {
      $(this).addClass('codeblock');
    }
    hljs.highlightBlock(block);
  });
});
</script>




    
  </body>
</html>

